//
// Created by wujehy on 2020/7/9.
//

#include "TimerTask.h"
#include "Common.h"

using namespace GeeJoan::Common;

int64_t TimerTask::addTask(int64_t time, Task task)
{
    if (time < getCurrentTime())
    {
        return -1;
    }
    int64_t current_id = m_taskid++;
    taskid_task_map[current_id] = task;
    auto findTime = time_taskids_map.find( time );
    if (findTime != time_taskids_map.end())
    {
        // 存在 则 直接添加
        findTime->second->push_back( current_id );
    } else
    {
        std::shared_ptr<std::vector<int64_t>> tasklist = std::shared_ptr<std::vector<int64_t>>(
                new std::vector<int64_t> );
        time_taskids_map.insert( std::pair<int64_t, std::shared_ptr<std::vector<int64_t>>>( time, tasklist ));
        tasklist->push_back( current_id );
    }
    return current_id;
}

int TimerTask::removeTask(int64_t taskid)
{
    auto find = taskid_task_map.find( taskid );

    if (find != taskid_task_map.end())
    {
        taskid_task_map.erase( taskid );
    } else
    {
        return -1;
    }
    return 0;
}


int TimerTask::join()
{
    m_hander.join();
    return 0;
}

void TimerTask::runTask(int64_t taskid)
{
    auto find = taskid_task_map.find( taskid );
    if (find != taskid_task_map.end())
    {
        find->second();
        taskid_task_map.erase( find );
    }
}

void TimerTask::init()
{

    m_hander = std::thread( [&]()
                            {
                                while (m_do_run)
                                {
                                    std::this_thread::sleep_for( std::chrono::seconds( 1 ));
                                    int64_t currentTime = getCurrentTime();
                                    auto find = this->time_taskids_map.find( currentTime );
                                    if (find != time_taskids_map.end())
                                    {
                                        for (int i = 0; i < find->second->size(); ++i)
                                        {
                                            runTask( find->second->at( i ));
                                        }
                                        time_taskids_map.erase( find );
                                    }
                                }
                            } );
}

void TimerTask::setDoRun(bool mDoRun)
{
    m_do_run = mDoRun;
}

int64_t TimerTask::getCurrentTime()
{
    return Common::getCurrentMill() / 1000;
}
